package com.onesports.rabbitmq.config;

import com.onesports.rabbitmq.message.IRabbitmqConfirmCallback;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

/**
 * @Author: HUANG GY.
 * @Date: 2020/6/19 14:19
 * @Description: 消息确认回调函数配置
 */
@Configuration
public class RabbitConfig {

    @Autowired
    private IRabbitmqConfirmCallback rabbitmqConfirmCallback ;

    /**
     *  生产者推送消息的消息确认调用回调函数
     *      ①消息推送到server，但是在server里找不到交换机 :这种情况触发的是 ConfirmCallback 回调函数,确认情况是false
     *      ②消息推送到server，找到交换机了，但是没找到队列:两个回调函数都用到了，确认情况是true
     *      ③消息推送到sever，交换机和队列啥都没找到 :这种情况触发的是 ConfirmCallback 回调函数,确认情况是false
     *      ④消息推送成功：这种情况触发的是 ConfirmCallback 回调函数，确认情况是true
     *
     * @param connectionFactory 连接工厂
     * @return
     */
    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
        rabbitTemplate.setMandatory(true);
        //消息确认回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                //消息发送成功
                rabbitmqConfirmCallback.confirm(correlationData,ack,cause);
            }
        });

        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                //消息丢失
                rabbitmqConfirmCallback.returnedMessage(message,replyCode,replyText,exchange,routingKey);
            }
        });

        return rabbitTemplate;
    }
}
